#include"LogStream.h"
using namespace Log;

LogStream::LogStream(int bufferSize) :
    bufferSize_(bufferSize)
{
    buffers_.emplace_back(new LogBuffer(bufferSize_));
}
LogStream& LogStream::operator<<(size_t v) {
    auto tmp = std::to_string(v);
    append(tmp.c_str(), tmp.size());
    return *this;
}

LogStream& LogStream::operator<<(int v) {
    auto tmp=std::to_string(v);
    append(tmp.c_str(), tmp.size());
    return *this;
}

LogStream& LogStream::operator<<(ssize_t v) {
    auto tmp = std::to_string(v);
    append(tmp.c_str(), tmp.size());
    return *this;
}


//LogStream& LogStream::operator<<(uint64_t v) {
//    auto tmp = std::to_string(v);
//    append(tmp.c_str(), tmp.size());
//    return *this;
//}

LogStream& LogStream::operator<<(char v)
{
    append(&v, 1);
    return *this;
}

template<int N>
LogStream& LogStream::operator<<(const char(&str)[N]) {
    append(str, N - 1);
    return *this;
}

LogStream& LogStream::operator<<(const char* str)
{
    if (str)
    {
        append(str, strlen(str));
    }
    else
    {
        append("(null)", 6);
    }
    return *this;
}

LogStream& LogStream::operator<<(const unsigned char* str)
{
    return operator<<(reinterpret_cast<const char*>(str));
}

LogStream& LogStream::operator<<(const std::string& v)
{
    append(v.c_str(), v.size());
    return *this;
}

LogStream& LogStream::operator<<(const SourceFile& v) {
    append(v.data(), v.size());
    return *this;
}


void LogStream::append(const char* data, int size) {
    int n = 0;
    while (n = buffers_.back()->append(data, size) < size) {
        buffers_.emplace_back(new LogBuffer(bufferSize_));
        data += n;
        size -= n;
    }
}

const std::vector<std::unique_ptr<LogBuffer>>& LogStream::buffers() const {
    return buffers_; 
}

void LogStream::clearBuffer() {
    buffers_.erase(buffers_.begin() + 1, buffers_.end());
    buffers_.back()->clear();
}

